home *** CD-ROM | disk | FTP | other *** search
- /*====================================================
- ARTemis
- (version 1.3)
- FM-TOWNS 用ペイントツール
-
- by 松内 良介 1994
- ====================================================*/
- #if 0
- pic.c : 「画像」
-
- pic_init
-
- pic_new(wid,ht)
- pic_destroy(pic)
- pic_dup(pic)
-
- static void pic_updatePoint(PIC* pic,int x,int y)
- static void pic_updateRect(PIC* pic, int x,int y,int wid,int ht)
-
- pic_setPixelXy(pic,x,y,pixel) 1ピクセルの色を設定
- pic_getPixelXy(pic,x,y,pixel) 1ピクセルの色を取得
- void pic_grayPset(PIC* pic,int x,int y,int gray,PIXEL *pixel);
- void pic_psetpen(PIC *pic,int x,int y,Pen pen,PIXEL *pixel);
- void pic_grayhline(PIC *pic,int x1,int x2,int y,int gray,PIXEL *pixel);
- void pic_clear(PIC *pic, PIXEL *pixel);
- void pic_kosuriStart(PIC* pic,int x,int y,char* graypat,int wid,int ht);
- void pic_kosuriDrag(PIC* pic,int x,int y,int r);
-
- void pic_copy(PIC* picSrc, FRAME* frSrc, PIC* picDest, POINT* ptDest);
- void pic_copyarea(PIC* picSrc, AREA areaSrc, PIC* picDest, POINT* ptDest);
- void pic_paint(PIC *pic, int x,int y, PIXEL* pix);
- void pic_blot(PIC *pic,int x,int y,PIXEL* pix,int branch,int depth)
- void pic_diffusePen(PIC* pic,int x,int y,Pen pen);
- void pic_sandPen(PIC* pic,int x,int y,Pen pen);
- void pic_polygon(PIC* pic,POINT* points,int nPoint,PIXEL* pix);
- void pic_fillarea(PIC* pic,AREA area,PIXEL* pix);
-
- pic_beginUpDate(pic) 更新領域のクリア
- pic_endUpDate(pic,frame) 更新終了;更新領域の取得
-
- pic_loadTIFF_
- pic_saveTIFF_
- pic_getRectImage(pic,buf,frame)
- void pic_getScrBitMap(PIC* pic,SCRBITMAP bm,int ofsx,int ofsy, FRAME *fr);
- // 画像内の fr の領域を bm の ofsx, ofsy に転送する
-
- pixel_setRgb(pixel, r,g,b)
- pixel_getRgb(pixel, r,g,b)
- #endif
-
- #define MODULE_PIC
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <winb.h>
- #include <memory.h>
- #include <te.h>
- #include <fntb.h>
- #include <gui.h>
- #include <egb.h>
-
- #include "art.h"
- #include "pic.h"
- #include "subgrp.h"
- #include "guisub.h"
- #include "pensel.h"
-
- static char* tempBuf = NULL;
-
- static uint _31_255[] =
- { 0,8,16,25, 33,41,49,58, 66,74,82,90, 99,107,115,123,
- 132,140,148,156, 165,173,181,189, 197,206,214,222,
- 230,239,247,255};
-
- int pic_init(void)
- {
- return 0;
- }
-
- void pic_close(void)
- {
- }
-
- PIC *pic_new(int pixelsize, int wid,int ht)
- {
- PIC *pic;
- if ((pic = TL_calloc(1, sizeof(PIC))) == NULL)
- return NULL;
- if ((pic->buf = TL_calloc(1,wid*ht*pixelsize/8)) == NULL)
- { TL_free(pic); return NULL; }
- memset(pic->buf, 0xff, wid*ht*pixelsize/8);
- pic->wid = wid;
- pic->ht = ht;
- pic->pixelsize = pixelsize;
- return pic;
- }
-
- PIC* pic_dup(PIC* pic)
- {
- PIC* newpic;
- if ((newpic = TL_calloc(1,sizeof(PIC))) == NULL)
- return NULL;
- if ((newpic->buf = TL_calloc(1,pic->pixelsize*pic->wid*pic->ht/8)) == NULL)
- { TL_free(newpic); return NULL; }
- memcpy(newpic->buf, pic->buf, pic->wid*pic->ht*pic->pixelsize/8);
- newpic->wid = pic->wid;
- newpic->ht = pic->ht;
- newpic->pixelsize = pic->pixelsize;
- return newpic;
- }
-
- void pic_destroy(PIC *pic)
- {
- TL_free(pic->buf);
- TL_free(pic);
- }
-
- /*--------------------------------------------------------*/
- /* PIC更新情報の更新 */
- /*--------------------------------------------------------*/
-
- static void pic_updatePoint(PIC* pic,int x,int y)
- {
- if (pic->update.lupx < 0)
- {
- pic->update.lupx = pic->update.rdwx = x;
- pic->update.lupy = pic->update.rdwy = y;
- }
- else
- {
- if (x < pic->update.lupx)
- pic->update.lupx = x;
- else if (pic->update.rdwx < x)
- pic->update.rdwx = x;
- if (y < pic->update.lupy)
- pic->update.lupy = y;
- else if (pic->update.rdwy < y)
- pic->update.rdwy = y;
- }
- }
-
- static void pic_updateRect(PIC* pic, int x,int y,int wid,int ht)
- {
- // 内容変更領域を更新
- int left,top,right,bottom;
- left = _max(0,x);
- right = _min(pic->wid-1,x+wid-1);
- top = _max(0,y);
- bottom = _min(pic->ht-1,y+ht-1);
- if (pic->update.X < 0)
- {
- pic->update.X = left;
- pic->update.X2 = right;
- pic->update.Y = top;
- pic->update.Y2 = bottom;
- }
- else
- {
- #define R (pic->update)
- R.X = _min(R.X, left);
- R.X2 = _max(R.X2, right);
- R.Y = _min(R.Y, top);
- R.Y2 = _max(R.Y2, bottom);
- #undef R
- }
- }
-
- /*--------------------------------------------------------*/
- /* ピクセルの色の設定・取得 */
- /*--------------------------------------------------------*/
-
- void pic_setPixelXy(PIC *pic, int x, int y, PIXEL *pixel)
- /* 1ピクセルの色を設定 */
- {
- if (x < 0 || pic->wid<=x || y < 0 || pic->ht<=y)
- return;
- if (pic->pixelsize == 16)
- *(unsigned short*)&pic->buf[(pic->wid * y + x) * 2] = CODE32K(*pixel);
- else
- {
- char *p = PICADDR(pic,x,y);
- uint col = CODE16M(*pixel);
- SETBYTE3(p,col);
- }
- pic_updatePoint(pic, x,y);
- }
-
- void pic_grayPset(PIC* pic,int x,int y,int gray,PIXEL* pixel)
- {
- if (x < 0 || pic->wid<=x || y < 0 || pic->ht<=y)
- return;
- if (pic->pixelsize == 16)
- {
- ushort* p = (ushort*)PICADDR(pic,x,y);
- int col = CODE32K(*pixel);
- int sr,sg,sb,dr,dg,db;
- GETRGB31(*p, dr,dg,db);
- GETRGB31(col, sr,sg,sb);
- dr = (dr * (255-gray) + sr * gray) / 255;
- dg = (dg * (255-gray) + sg * gray) / 255;
- db = (db * (255-gray) + sb * gray) / 255;
- SETRGB31(*p, dr,dg,db);
- }
- else
- {
- char* p = PICADDR(pic,x,y);
- int sr,sg,sb,dr,dg,db;
- sr=pixel->r,sg=pixel->g,sb=pixel->b;
- dr=p[0],dg=p[1],db=p[2];
- dr = (dr * (255-gray) + sr * gray) / 255;
- dg = (dg * (255-gray) + sg * gray) / 255;
- db = (db * (255-gray) + sb * gray) / 255;
- p[0]=dr,p[1]=dg,p[2]=db;
- }
- pic_updatePoint(pic, x,y);
- }
-
- void pic_getPixelXy(PIC *pic, int x, int y, PIXEL *pixel)
- /* 1ピクセルの色を取得 */
- {
- if (x < 0 || pic->wid<=x || y < 0 || pic->ht<=y)
- return;
- if (pic->pixelsize == 16)
- {
- int col = *(unsigned short*)&pic->buf[(pic->wid * y + x) * 2];
- int r,g,b;
- GETRGB31(col,r,g,b);
- pixel->r = _31_255[r];
- pixel->g = _31_255[g];
- pixel->b = _31_255[b];
- }
- else
- {
- char *p = PICADDR(pic,x,y);
- pixel->r = p[0];
- pixel->g = p[1];
- pixel->b = p[2];
- }
- }
-
- /*--------------------------------------------------------*/
- /* 濃度分布の描画 */
- /*--------------------------------------------------------*/
-
- void pic_psetpen(PIC *pic,int x,int y,Pen pen,PIXEL *pixel)
- {
- uint mix = pensel_getmix();
- x -= pen->ofsx;
- y -= pen->ofsy;
- for (int i=0; i<pen->ht; i++)
- {
- int dy = y + i;
- if (dy < 0 || pic->ht <= dy)
- continue;
- char *penp = pen->buf + pen->wid * i;
- if (pic->pixelsize == 16)
- {
- char *dp = PICADDR(pic,x,dy);
- int col = CODE32K(*pixel);
- int sr,sg,sb,dr,dg,db;
- GETRGB31(col,sr,sg,sb);
- for (int j=0; j<pen->wid; j++,dp+=2,penp++)
- {
- if (*penp == 0 || x+j < 0 || pic->wid <= x+j)
- continue;
- uint mr = (mix * (*penp) + 127) / 255;
- GETRGB31(WORD(dp),dr,dg,db);
- dr = (dr * (255-mr) + sr * (uint)mr + 127)/255;
- dg = (dg * (255-mr) + sg * (uint)mr + 127)/255;
- db = (db * (255-mr) + sb * (uint)mr + 127)/255;
- SETRGB31(WORD(dp),dr,dg,db);
- }
- }
- else
- {
- char *dp = PICADDR(pic,x,dy);
- int sr,sg,sb,dr,dg,db;
- sr=pixel->r,sg=pixel->g,sb=pixel->b;
- for (int j=0; j<pen->wid; j++,dp+=3,penp++)
- {
- if (*penp == 0 || x+j < 0 || pic->wid <= x+j)
- continue;
- uint mr = (mix * (*penp) + 127) / 255;
- dr=dp[0],dg=dp[1],db=dp[2];
- dr = (dr * (255-mr) + sr * (uint)mr + 127)/255;
- dg = (dg * (255-mr) + sg * (uint)mr + 127)/255;
- db = (db * (255-mr) + sb * (uint)mr + 127)/255;
- dp[0]=dr,dp[1]=dg,dp[2]=db;
- }
- }
- }
- pic_updateRect(pic,x,y,pen->wid,pen->ht);
- }
-
- /*--------------------------------------------------------*/
- /* 水平直線の描画 */
- /*--------------------------------------------------------*/
-
- void pic_grayhline(PIC *pic,int x1,int x2,int y,int gray,PIXEL *pixel)
- {
- if (x1 >= x2)
- SWAP_INT(x1,x2)
- if (y < 0 || pic->ht <= y)
- return;
- x1 = _max(0,x1);
- x2 = _min(pic->wid-1,x2);
- if (x2 < x1)
- return;
- if (pic->pixelsize == 16)
- {
- char *dp = PICADDR(pic,x1,y);
- ushort col = CODE32K(*pixel);
- if (gray >= 255)
- {
- for (int i=x1; i<=x2; i++,dp+=2)
- WORD(dp) = col;
- }
- else if (gray > 0)
- {
- int sr,sg,sb,dr,dg,db;
- int igray = 255 - gray;
- GETRGB31(col, sr,sg,sb);
- for (int i=x1; i<=x2; i++,dp+=2)
- {
- GETRGB31(WORD(dp), dr,dg,db);
- dr = (dr * igray + sr * gray + 128) / 255;
- dg = (dg * igray + sg * gray + 128) / 255;
- db = (db * igray + sb * gray + 128) / 255;
- SETRGB31(WORD(dp), dr,dg,db);
- }
- }
- }
- else if (pic->pixelsize == 24)
- {
- char *dp = PICADDR(pic,x1,y);
- if (gray >= 255)
- {
- for (int i=x1; i<=x2; i++,dp+=3)
- dp[0]=pixel->r,dp[1]=pixel->g,dp[2]=pixel->b;
- }
- else if (gray > 0)
- {
- int sr,sg,sb,dr,dg,db;
- sr=pixel->r,sg=pixel->g,sb=pixel->b;
- int igray = 255 - gray;
- for (int i=x1; i<=x2; i++,dp+=3)
- {
- dr=dp[0],dg=dp[1],db=dp[2];
- dr = (dr * igray + sr * (uint)gray + 127)/255;
- dg = (dg * igray + sg * (uint)gray + 127)/255;
- db = (db * igray + sb * (uint)gray + 127)/255;
- dp[0]=dr,dp[1]=dg,dp[2]=db;
- }
- }
- }
- pic_updateRect(pic,x1,y,x2-x1+1,1);
- }
-
- /*--------------------------------------------------------*/
- /* クリア */
- /*--------------------------------------------------------*/
-
- void pic_clear(PIC *pic, PIXEL *pixel)
- {
- int i;
- for (i = 0; i < pic->ht; i++)
- pic_grayhline(pic, 0, pic->wid-1, i, 255, pixel);
- }
-
- /*--------------------------------------------------------*/
- /* こすり処理 */
- /*--------------------------------------------------------*/
-
- char *kosuri_graypat;
- int kosuri_x, kosuri_y;
- int kosuri_wid,kosuri_ht;
-
- void pic_kosuriStart(PIC* pic,int x,int y,char* graypat,int wid,int ht)
- // x,y : ペンの左上端の PIC 座標
- // graypat : ペンの濃度デ-タ
- // wid,ht : ペンの大きさ
- {
- kosuri_graypat = graypat;
- kosuri_x = x;
- kosuri_y = y;
- kosuri_wid = wid;
- kosuri_ht = ht;
- if (tempBuf != NULL)
- TL_free(tempBuf);
- tempBuf = TL_calloc(1,pic->pixelsize*kosuri_wid*kosuri_ht/8);
- }
-
- void pic_kosuriDrag(PIC* pic,int x,int y,int r)
- // x,y : ペンの左上端の PIC 座標
- // r : こすり強さ (0~255)
- {
- if (tempBuf == NULL)
- return;
- int i,j;
- // 前のペンの位置の色を tempBuf に格納
- char *p = kosuri_graypat;
- for (i=0; i<kosuri_ht; i++)
- {
- if (kosuri_y+i < 0)
- continue;
- else if (kosuri_y+i >= pic->ht)
- break;
- char *ptrpic;
- ptrpic = pic->buf + PICOFFSET(pic,kosuri_x,kosuri_y+i);
- char *ptrbuf;
- ptrbuf = tempBuf + (kosuri_wid*i) * pic->pixelsize/8;
- if (pic->pixelsize == 16)
- {
- for (j=0; j<kosuri_wid; j++,p++,ptrpic+=2,ptrbuf+=2)
- {
- if (kosuri_x+j < 0)
- continue;
- else if (kosuri_x+j >= pic->wid)
- break;
- if (*p == 0)
- continue;
- WORD(ptrbuf) = WORD(ptrpic);
- }
- }
- else
- {
- for (j=0; j<kosuri_wid; j++,p++,ptrpic+=3,ptrbuf+=3)
- {
- if (kosuri_x+j < 0)
- continue;
- else if (kosuri_x+j >= pic->wid)
- break;
- if (*p == 0)
- continue;
- WORD(ptrbuf) = WORD(ptrpic);
- BYTE(ptrbuf+2) = BYTE(ptrpic+2);
- }
- }
- }
- // 新しいペンの位置と色をまぜあわせる
- p = kosuri_graypat;
- for (i=0; i<kosuri_ht; i++)
- {
- if (y+i < 0)
- continue;
- else if (y+i >= pic->ht)
- break;
- char *ptrpic;
- ptrpic = pic->buf + PICOFFSET(pic,x,y+i);
- char *ptrbuf;
- ptrbuf = tempBuf + (kosuri_wid*i) * pic->pixelsize/8;
- if (pic->pixelsize == 16)
- {
- for (j=0; j<kosuri_wid; j++,p++,ptrpic+=2,ptrbuf+=2)
- {
- if (x+j < 0)
- continue;
- else if (x+j >= pic->wid)
- break;
- if (*p == 0)
- continue;
- unsigned int sc,dc, sr,sg,sb,dr,dg,db,tr,tg,tb;
- sc = WORD(ptrbuf);
- dc = WORD(ptrpic);
- sr=(sc>>5)&31,sg=(sc>>10)&31,sb=sc&31;
- dr=(dc>>5)&31,dg=(dc>>10)&31,db=dc&31;
- tr = (sr*r+dr*(255-r)+127)/255;
- tg = (sg*r+dg*(255-r)+127)/255;
- tb = (sb*r+db*(255-r)+127)/255;
- WORD(ptrpic) = (tg<<10)|(tr<<5)|tb;
- tr = (sr*(255-r)+dr*r+127)/255;
- tg = (sg*(255-r)+dg*r+127)/255;
- tb = (sb*(255-r)+db*r+127)/255;
- WORD(ptrbuf) = (tg<<10)|(tr<<5)|tb;
- }
- }
- else
- {
- for (j=0; j<kosuri_wid; j++,p++,ptrpic+=3,ptrbuf+=3)
- {
- if (x+j < 0)
- continue;
- else if (x+j >= pic->wid)
- break;
- if (*p == 0)
- continue;
- unsigned int sr,sg,sb,dr,dg,db,tr,tg,tb;
- sr=ptrbuf[0],sg=ptrbuf[1],sb=ptrbuf[2];
- dr=ptrpic[0],dg=ptrpic[1],db=ptrpic[2];
- tr = (sr*r+dr*(255-r)+127)/255;
- tg = (sg*r+dg*(255-r)+127)/255;
- tb = (sb*r+db*(255-r)+127)/255;
- ptrpic[0]=tr,ptrpic[1]=tg,ptrpic[2]=tb;
- tr = (sr*(255-r)+dr*r+127)/255;
- tg = (sg*(255-r)+dg*r+127)/255;
- tb = (sb*(255-r)+db*r+127)/255;
- ptrbuf[0]=tr,ptrbuf[1]=tg,ptrbuf[2]=tb;
- }
- }
- }
- pic_updateRect(pic, x,y,kosuri_wid,kosuri_ht);
- // 次のこすりドラッグ
- kosuri_x = x;
- kosuri_y = y;
- }
-
- /*--------------------------------------------------------*/
- /* ペン先ぼかし */
- /*--------------------------------------------------------*/
-
- void pic_diffusePen(PIC* pic,int x,int y,Pen pen)
- {
- int picxbytes = pic->wid * pic->pixelsize / 8;
- int picy = y - pen->ofsy;
- for (int i=0; i<pen->ht; i++,picy++)
- {
- if (picy < 0 || pic->ht <= picy)
- continue;
- int picx = x - pen->ofsx;
- char* penp = pen->buf + PENOFFSET(pen,0,i);
- char* picp = pic->buf + PICOFFSET(pic,picx,picy);
- if (pic->pixelsize == 16)
- {
- for (int j=0; j<pen->wid; j++,picx++,penp++,picp+=2)
- {
- if (*penp == 0 || picx < 0 || pic->wid <= picx)
- continue;
- #define DIF 6
- uint r,g,b;
- uint sum,rsum,gsum,bsum; sum=rsum=gsum=bsum=0;
- GETRGB31(WORD(picp),r,g,b);
- rsum+=r*DIF; gsum+=g*DIF; bsum+=b*DIF; sum+=DIF;
- if (picy-1 >= 0)
- { GETRGB31(WORD(picp-picxbytes),r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- if (picy+1 < pic->ht)
- { GETRGB31(WORD(picp+picxbytes),r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- if (picx-1 >= 0)
- { GETRGB31(WORD(picp-2),r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- if (picx+1 < pic->wid)
- { GETRGB31(WORD(picp+2),r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- rsum = (rsum+sum/2) / sum;
- gsum = (gsum+sum/2) / sum;
- bsum = (bsum+sum/2) / sum;
- SETRGB31(WORD(picp),rsum,gsum,bsum);
- #undef DIF
- }
- }
- else
- {
- for (int j=0; j<pen->wid; j++,picx++,penp++,picp+=3)
- {
- if (*penp == 0 || picx < 0 || pic->wid <= picx)
- continue;
- #define DIF 6
- uint r,g,b;
- uint sum,rsum,gsum,bsum; sum=rsum=gsum=bsum=0;
- r=picp[0],g=picp[1],b=picp[2];
- rsum+=r*DIF; gsum+=g*DIF; bsum+=b*DIF; sum+=DIF;
- if (picy-1 >= 0)
- { GET3BYTE(picp-picxbytes,r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- if (picy+1 < pic->ht)
- { GET3BYTE(picp+picxbytes,r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- if (picx-1 >= 0)
- { GET3BYTE(picp-3,r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- if (picx+1 < pic->wid)
- { GET3BYTE(picp+3,r,g,b);
- rsum+=r,gsum+=g,bsum+=b,sum++; }
- rsum = (rsum+sum/2) / sum;
- gsum = (gsum+sum/2) / sum;
- bsum = (bsum+sum/2) / sum;
- picp[0]=rsum,picp[1]=gsum,picp[2]=bsum;
- #undef DIF
- }
- }
- }
- pic_updateRect(pic, x-pen->ofsx, y-pen->ofsy, pen->wid, pen->ht);
- }
-
- void pic_sandPen(PIC* pic,int x,int y,Pen pen)
- {
- int picxbytes = pic->wid * pic->pixelsize / 8;
- int picy = y - pen->ofsy;
- for (int i=0; i<pen->ht; i++,picy++)
- {
- if (picy < 0 || pic->ht <= picy)
- continue;
- int picx = x - pen->ofsx;
- char* penp = pen->buf + PENOFFSET(pen,0,i);
- char* picp = pic->buf + PICOFFSET(pic,picx,picy);
- if (pic->pixelsize == 16)
- {
- for (int j=0; j<pen->wid; j++,picx++,penp++,picp+=2)
- {
- if (*penp == 0 || picx < 0 || pic->wid <= picx)
- continue;
- #define DIF 6
- int r,g,b;
- GETRGB31(WORD(picp),r,g,b);
- r = _min(31,_max(0, r + rand() % 3 - 1));
- g = _min(31,_max(0, g + rand() % 3 - 1));
- b = _min(31,_max(0, b + rand() % 3 - 1));
- SETRGB31(WORD(picp),r,g,b);
- #undef DIF
- }
- }
- else
- {
- for (int j=0; j<pen->wid; j++,picx++,penp++,picp+=3)
- {
- if (*penp == 0 || picx < 0 || pic->wid <= picx)
- continue;
- int r,g,b;
- r=picp[0],g=picp[1],b=picp[2];
- r = _min(255,_max(0, r + (rand() % 13 - 6)));
- g = _min(255,_max(0, g + (rand() % 13 - 6)));
- b = _min(255,_max(0, b + (rand() % 13 - 6)));
- picp[0]=r,picp[1]=g,picp[2]=b;
- }
- }
- }
- pic_updateRect(pic, x-pen->ofsx, y-pen->ofsy, pen->wid, pen->ht);
- }
-
- /*--------------------------------------------------------*/
- /* 更新の開始・終了 */
- /*--------------------------------------------------------*/
-
- void pic_beginUpDate(PIC *pic)
- {
- pic->update.lupx = -1;
- }
-
- void pic_endUpDate(PIC *pic, FRAME *frame)
- {
- pic->update.WID = pic->update.X2 - pic->update.X + 1;
- pic->update.HT = pic->update.Y2 - pic->update.Y + 1;
- *frame = pic->update;
- }
-
- static PIC *_pic;
- static TIFFINFO tiffinfo;
-
- static int putimage(char *buf, int ofsy, int ht)
- {
- for (int i=0; i<ht; i++)
- {
- if (ofsy+i >= _pic->ht)
- break;
- char *dp = _pic->buf + PICOFFSET(_pic, 0, ofsy+i);
- char *sp = buf + (tiffinfo.wid*tiffinfo.pixelsize/8)*i;
- int wid = _min(_pic->wid, tiffinfo.wid);
- int t = wid * _pic->pixelsize / 8;
- memcpy(dp, sp, t);
- }
- return 0;
- }
-
- static int getimage(char *buf,int ofsy,int ht)
- {
- for (int i=0; i<ht; i++)
- {
- if (ofsy+i >= _pic->ht)
- break;
- char *dp = buf + (tiffinfo.wid*tiffinfo.pixelsize/8)*i;
- char *sp = _pic->buf + PICOFFSET(_pic, 0, ofsy+i);
- int wid = _min(_pic->wid, tiffinfo.wid);
- int t = wid * _pic->pixelsize / 8;
- memcpy(dp, sp, t);
- }
- return 0;
- }
-
- int pic_loadTIFF_(PIC *pic, char *fname)
- /* PIC構造体内に TIFF ファイルの画像をロードする */
- {
- _pic = pic;
- int ret;
- if ((ret = RM_getTIFFinfo(fname, &tiffinfo)) != NOERR)
- return ret;
- ret = RM_loadTIFF(fname, putimage, (int(*)())0);
- return ret;
- }
-
- int pic_saveTIFF_(PIC *pic, char *fname)
- {
- _pic = pic;
- tiffinfo.wid = pic->wid;
- tiffinfo.ht = pic->ht;
- tiffinfo.pixelsize = pic->pixelsize;
- int ret;
- ret = RM_saveTIFF(fname, pic->pixelsize, pic->wid, pic->ht, TRUE,
- getimage, (int(*)())0);
- return ret;
- }
-
- void pic_getScrBitMap(PIC* pic,SCRBITMAP bm, int ofsx, int ofsy, FRAME *_fr,
- int zoom)
- // 画像内の fr(x,y,wid,ht) の領域を bm の ofsx, ofsy に転送する
- // 画面イメージへの変換を行う
- {
- int i;
- FRAME fr;
- fr = *_fr;
- if (ofsx < 0)
- fr.X+=(-ofsx)/zoom, fr.WID-=(-ofsx)/zoom, ofsx=0;
- if (ofsy < 0)
- fr.Y+=(-ofsy)/zoom, fr.HT-=(-ofsy)/zoom, ofsy=0;
- if (fr.WID <= 0 && fr.HT <= 0)
- return;
- int wid = _min(fr.WID, pic->wid - fr.X,
- (bm->wid - ofsx + zoom-1) / zoom);
- // ↑実際の転送ドット数
- if (wid <= 0)
- return;
- int dcnt = _min(zoom, bm->wid - ofsx - (wid-1)*zoom);
- // ↑SCRBITMAP側の右端のピクセルの横幅
- int dxbytes = bm->wid * bm->pixelsize / 8;
- // ↑SCRBITMAPの横バイト数
- int dxcnt = (wid-1)*zoom + dcnt;
- // ↑SCRBITMAP側の転送領域の横ピクセル数
- for (i=0; i<fr.HT; i++)
- {
- int dy = ofsy + zoom * i;
- int sy = fr.Y + i;
- if (sy < 0 || pic->ht <= sy)
- continue;
- if (dy < 0 || bm->ht <= dy)
- continue;
- if (wid == 0)
- break;
- char *dp = bm->buf + BMOFFSET(bm, ofsx, dy);
- char *dp0 = dp;
- char *sp = pic->buf + PICOFFSET(pic, fr.X, sy);
- if (zoom==1 && pic->pixelsize == 16 && bm->pixelsize == 16)
- memcpy(dp,sp,wid * 2);
- else if (pic->pixelsize == 16 && bm->pixelsize == 16)
- {
- int j;
- if (zoom == 2)
- for (j=0; j<wid-1; j++,sp+=2,dp+=4)
- WORD(dp)=WORD(dp+2)=WORD(sp);
- else if (zoom==3)
- for (j=0; j<wid-1; j++,sp+=2,dp+=6)
- WORD(dp)=WORD(dp+2)=WORD(dp+4)=WORD(sp);
- else if (zoom==4)
- for (j=0; j<wid-1; j++,sp+=2,dp+=8)
- WORD(dp)=WORD(dp+2)=WORD(dp+4)=WORD(dp+6)=WORD(sp);
- else if (zoom==5)
- for (j=0; j<wid-1; j++,sp+=2,dp+=10)
- WORD(dp)=WORD(dp+2)=WORD(dp+4)=WORD(dp+6)=
- WORD(dp+8)=WORD(sp);
- else if (zoom==6)
- for (j=0; j<wid-1; j++,sp+=2,dp+=12)
- WORD(dp)=WORD(dp+2)=WORD(dp+4)=WORD(dp+6)=
- WORD(dp+8)=WORD(dp+10)=WORD(sp);
- else if (zoom==7)
- for (j=0; j<wid-1; j++,sp+=2,dp+=14)
- WORD(dp)=WORD(dp+2)=WORD(dp+4)=WORD(dp+6)=
- WORD(dp+8)=WORD(dp+10)=WORD(dp+12)=WORD(sp);
- else if (zoom==8)
- for (j=0; j<wid-1; j++,sp+=2,dp+=16)
- WORD(dp)=WORD(dp+2)=WORD(dp+4)=WORD(dp+6)=
- WORD(dp+8)=WORD(dp+10)=WORD(dp+12)=WORD(dp+14)=WORD(sp);
- // SCRBITMAP 側の右端のドットだけ特別扱い
- for (j=0; j<dcnt; j++,dp+=2)
- WORD(dp)=WORD(sp);
- }
- else if (pic->pixelsize == 16 && bm->pixelsize == 24)
- {
- for (int j=0; j<wid-1; j++,sp+=2)
- {
- int r,g,b;
- GETRGB31(WORD(sp),r,g,b);
- r=_31_255[r]; g=_31_255[g], b=_31_255[b];
- for (int k=0; k<zoom; k++,dp+=3)
- dp[0]=r,dp[1]=g,dp[2]=b;
- }
- int r,g,b;
- GETRGB31(WORD(sp),r,g,b);
- r=_31_255[r]; g=_31_255[g], b=_31_255[b];
- for (int k=0; k<dcnt; k++,dp+=3)
- dp[0]=r,dp[1]=g,dp[2]=b;
- }
- else if (pic->pixelsize == 24 && bm->pixelsize == 16)
- {
- for (int j=0; j<wid-1; j++,sp+=3)
- {
- int r,g,b;
- r=sp[0],g=sp[1],b=sp[2];
- r>>=3,g>>=3,b>>=3;
- for (int k=0; k<zoom; k++,dp+=2)
- SETRGB31(WORD(dp), r,g,b);
- }
- int r,g,b;
- r=sp[0],g=sp[1],b=sp[2];
- r>>=3,g>>=3,b>>=3;
- for (int k=0; k<dcnt; k++,dp+=2)
- SETRGB31(WORD(dp), r,g,b);
- }
- else if (pic->pixelsize == 24 && bm->pixelsize == 24)
- {
- for (int j=0; j<wid-1; j++,sp+=3)
- {
- for (int k=0; k<zoom; k++,dp+=3)
- dp[0]=sp[0],dp[1]=sp[1],dp[2]=sp[2];
- }
- for (int k=0; k<dcnt; k++,dp+=3)
- dp[0]=sp[0],dp[1]=sp[1],dp[2]=sp[2];
- }
- // 縦方向にひきのばす
- int t = dxcnt * bm->pixelsize / 8;
- for (int j=1; j < zoom && dy+j < bm->ht; j++)
- memcpy(dp0+dxbytes*j, dp0, t);
- }
- }
-
- /*--------------------------------------------------------*/
- /* ピクセル値 */
- /*--------------------------------------------------------*/
-
- void pixel_setRgb(PIXEL *pixel, int r, int g, int b)
- {
- pixel->r = (r < 0 ? 0 : r > 255 ? 255 : r);
- pixel->g = (g < 0 ? 0 : g > 255 ? 255 : g);
- pixel->b = (b < 0 ? 0 : b > 255 ? 255 : b);
- }
-
- void pixel_getRgb(PIXEL *pixel, int *r, int *g, int *b)
- {
- *r = pixel->r;
- *g = pixel->g;
- *b = pixel->b;
- }
-
- void pic_copy(PIC* picSrc, FRAME* frSrc, PIC* picDest, POINT* ptDest)
- // frSrc:(x,y,wid,ht)
- // update 管理を忘れないこと!
- {
- int i;
- if (frSrc->Y >= ptDest->y)
- {
- for (i=0; i<frSrc->HT; i++)
- {
- int sy = frSrc->Y+i;
- int dy = ptDest->y+i;
- if (sy < 0 || dy < 0)
- continue;
- if (sy >= picSrc->ht || dy >= picDest->ht)
- break;
- char *sp = picSrc->buf + PICOFFSET(picSrc,frSrc->X,frSrc->Y+i);
- char *dp = picDest->buf + PICOFFSET(picDest,ptDest->x,ptDest->y+i);
- int wid = _max(0,_min(frSrc->WID,
- picSrc->wid - frSrc->X,
- picDest->wid - ptDest->x));
- if (wid == 0)
- break;
- if (picSrc->pixelsize == picDest->pixelsize)
- memcpy(dp, sp, wid * picSrc->pixelsize / 8);
- else if (picSrc->pixelsize == 16 && picDest->pixelsize == 24)
- {
- for (int j=0; j<wid; j++,dp+=3,sp+=2)
- { int r,g,b; GETRGB31(WORD(sp), r,g,b);
- dp[0]=_31_255[r],dp[1]=_31_255[g],dp[2]=_31_255[b]; }
- }
- else if (picSrc->pixelsize == 24 && picDest->pixelsize == 16)
- {
- for (int j=0; j<wid; j++,dp+=2,sp+=3)
- SETRGB31(WORD(dp),sp[0]>>3,sp[1]>>3,sp[2]>>3);
- }
- }
- }
- else
- {
- for (i=0; i<frSrc->HT; i++)
- {
- int sy = frSrc->Y+frSrc->HT-1-i;
- int dy = ptDest->y+frSrc->HT-1-i;
- if (sy < 0 || dy < 0)
- break;
- if (sy >= picSrc->ht || dy >= picDest->ht)
- continue;
- char *sp = picSrc->buf + PICOFFSET(picSrc,frSrc->X,frSrc->Y+i);
- char *dp = picDest->buf + PICOFFSET(picDest,ptDest->x,ptDest->y+i);
- int wid = _max(0,_min(frSrc->WID,
- picSrc->wid - frSrc->X,
- picDest->wid - ptDest->x));
- if (wid == 0)
- break;
- if (picSrc->pixelsize == picDest->pixelsize)
- memcpy(dp, sp, wid * picSrc->pixelsize / 8);
- else if (picSrc->pixelsize == 16 && picDest->pixelsize == 24)
- {
- for (int j=0; j<wid; j++,dp+=3,sp+=2)
- { int r,g,b; GETRGB31(WORD(sp), r,g,b);
- dp[0]=_31_255[r],dp[1]=_31_255[g],dp[2]=_31_255[b]; }
- }
- else if (picSrc->pixelsize == 24 && picDest->pixelsize == 16)
- {
- for (int j=0; j<wid; j++,dp+=2,sp+=3)
- SETRGB31(WORD(dp),sp[0]>>3,sp[1]>>3,sp[2]>>3);
- }
- }
- }
- pic_updateRect(picDest, ptDest->x, ptDest->y, frSrc->WID, frSrc->HT);
- }
-
- void pic_paint(PIC *pic, int x,int y, PIXEL* pix)
- {
- PIXEL pixBack;
- #define ISBACK(pix) \
- ((pix).r==pixBack.r && (pix).g==pixBack.g && (pix).b==pixBack.b)
- pic_getPixelXy(pic,x,y,&pixBack);
- if (ISBACK(*pix))
- return;
- int mix = pensel_getmix();
- void hline(int x1,int x2,int y)
- {
- pic_grayhline(pic,x1,x2,y,mix,pix);
- }
- BOOL shouldPaint(int x,int y)
- {
- PIXEL pix;
- pic_getPixelXy(pic,x,y,&pix);
- if (ISBACK(pix))
- return TRUE;
- else
- return FALSE;
- }
- int srchleft(int x,int y)
- {
- int sx1;
- PIXEL pix;
- for (sx1=x; sx1 > 0; sx1--)
- {
- pic_getPixelXy(pic,sx1-1,y,&pix);
- if (!ISBACK(pix))
- break;
- }
- return sx1;
- }
- int srchright(int x,int y)
- {
- int sx2;
- PIXEL pix;
- for (sx2=x; sx2 < pic->wid-1; sx2++)
- {
- pic_getPixelXy(pic,sx2+1,y,&pix);
- if (!ISBACK(pix))
- break;
- }
- return sx2;
- }
- do_paint(x,y,pic->wid,pic->ht,hline,shouldPaint,srchleft,srchright);
- }
-
- void pic_blot(PIC *pic,int x,int y,int branch,int depth,PIXEL* pix)
- {
- uint mix = pensel_getmix();
- void pset(int x,int y,int gray)
- {
- pic_grayPset(pic,x,y,(gray*mix+127)/255,pix);
- }
- do_blot(x,y,branch,depth,pset);
- }
-
- void pic_polygon(PIC* pic,POINT* points,int nPoint,PIXEL* pix)
- {
- int mix = pensel_getmix();
- void hline(int x1,int x2,int y)
- {
- pic_grayhline(pic,x1,x2,y,mix,pix);
- }
- do_polygon(points,nPoint,hline);
- }
-
- void pic_copyarea(PIC* picSrc, AREA areaSrc, PIC* picDest, POINT* ptDest)
- {
- void hline(int x1,int x2,int y)
- {
- char *sp = PICADDR(picSrc,x1,y);
- char *dp = PICADDR(picDest,
- ptDest->x + (x1 - areaSrc->x), ptDest->y + (y - areaSrc->y));
- int wid = _max(0,_min( x2-x1+1,
- picSrc->wid - areaSrc->x,
- picDest->wid - ptDest->x));
- if (wid == 0)
- return;
- if (picSrc->pixelsize == picDest->pixelsize)
- memcpy(dp, sp, wid * picSrc->pixelsize / 8);
- else if (picSrc->pixelsize == 16 && picDest->pixelsize == 24)
- {
- for (int j=0; j<wid; j++,dp+=3,sp+=2)
- { int r,g,b; GETRGB31(WORD(sp), r,g,b);
- dp[0]=_31_255[r],dp[1]=_31_255[g],dp[2]=_31_255[b]; }
- }
- else if (picSrc->pixelsize == 24 && picDest->pixelsize == 16)
- {
- for (int j=0; j<wid; j++,dp+=2,sp+=3)
- SETRGB31(WORD(dp),sp[0]>>3,sp[1]>>3,sp[2]>>3);
- }
- }
- if (areaSrc->y >= ptDest->y)
- {
- for (int i=0; i<areaSrc->ht; i++)
- {
- int sy = areaSrc->y + i;
- int dy = ptDest->y + i;
- if (sy < 0 || dy < 0)
- continue;
- if (sy >= picSrc->ht || dy >= picDest->ht)
- break;
- area_forEachSect(areaSrc,sy,hline);
- }
- }
- else
- {
- for (int i=0; i<areaSrc->ht; i++)
- {
- int sy = areaSrc->y + areaSrc->ht - 1 - i;
- int dy = ptDest->y + areaSrc->ht - 1 - i;
- if (sy < 0 || dy < 0)
- break;
- if (sy >= picSrc->ht || dy >= picDest->ht)
- continue;
- area_forEachSect(areaSrc,sy,hline);
- }
- }
- pic_updateRect(picDest, ptDest->x, ptDest->y, areaSrc->wid, areaSrc->ht);
- }
-
- void pic_fillarea(PIC* pic,AREA area,PIXEL* pix)
- {
- int mix = pensel_getmix();
- void hline(int x1,int x2,int y)
- {
- pic_grayhline(pic,x1,x2,y,mix,pix);
- }
- for (int i=0; i<area->ht; i++)
- {
- int sy = area->y + i;
- if (sy < 0)
- continue;
- if (sy >= pic->ht)
- break;
- area_forEachSect(area, sy, hline);
- }
- pic_updateRect(pic, area->x, area->y, area->wid, area->ht);
- }
-